/**
 *
 * java在多线程情况下，经常会使用到线程的阻塞与唤醒，这里就为大家简单介绍一下以下几种阻塞/唤醒方式与区别
 *
 * suspend 与 resume
 * Java废弃 suspend() 去挂起线程的原因，是因为 suspend() 在导致线程暂停的同时，并不会去释放任何锁资源。其他线程都无法访问被它占用的锁。直到对应的线程执行 resume() 方法后，被挂起的线程才能继续，从而其它被阻塞在这个锁的线程才可以继续执行。
 * 但是，如果 resume() 操作出现在 suspend() 之前执行，那么线程将一直处于挂起状态，同时一直占用锁，这就产生了死锁。而且，对于被挂起的线程，它的线程状态居然还是 Runnable。
 *
 * wait与notify
 * wait与notify必须配合synchronized使用，因为调用之前必须持有锁，wait会立即释放锁，notify则是同步块执行完了才释放
 *
 * await与singal
 * Condition类提供，而Condition对象由new ReentLock().newCondition()获得，与wait和notify相同，因为使用Lock锁后无法使用wait方法
 *
 * park与unpark
 * LockSupport是一个非常方便实用的线程阻塞工具，它可以在线程任意位置让线程阻塞。和Thread.suspenf()相比，它弥补了由于resume()在前发生，导致线程无法继续执行的情况。和Object.wait()相比，它不需要先获得某个对象的锁，也不会抛出IException异常。可以唤醒指定线程。
 *
 * 总结
 * ！)wait与await区别：
 * wait与notify必须配合synchronized使用，因为调用之前必须持有锁，wait会立即释放锁，notify则是同步块执行完了才释放
 * 因为Lock没有使用synchronized机制，故无法使用wait方法区操作多线程，所以使用了Condition的await来操作
 * Lock实现主要是基于AQS，而AQS实现则是基于LockSupport，所以说LockSupport更底层，所以使用park效率会高一些
 *
 * 2)wait与sleep区别:
 * sleep方法只让出了CPU，而并不会释放同步资源锁
 * wait方法只让出了CPU，并且释放同步资源锁
 * * 阻塞：当一个线程试图获取一个内部的对象锁（非java.util.concurrent库中的锁），而该锁被其他线程持有，则该线程进入阻塞状态。
 *  * 等待：当一个线程等待另一个线程通知调度器一个条件时，该线程进入等待状态。
 *  *      例如调用：Object.wait()、Thread.join()以及等待Lock或Condition。
 *  * sleep（）和wait（）函数的区别：
 *  * （1）两者比较的共同之处是：两个方法都是使程序等待多少毫秒。
 *  * （2）最主要区别是：sleep（）方法没有释放锁。而wait（）方法释放了锁，使得其他线程可以使用同步控制块或者方法。
 *  * （3）sleep()会让出cpu，无锁或者其他线程不是同一个锁时才能获取
 *
 * 3)
 * Thread.sleep
 * sleep 方法可以让线程主动让出 CPU，但是并不会释放锁。
 * Thread.yield
 * yield 也可以让线程主动让出 CPU，然后和其他线程一起竞争 CPU，但是调度器也可以忽略 yield。哪些情况会用到 yield 呢？
 * 1. 一般在 debug 和 test 中使用。
 * 2. CPU 密集型应用主动让出 CPU 以避免过度占用 CPU，影响其他任务。
 * Thread.currentThread().suspend()
 * 该方法已过时。为啥呢？suspend 挂起线程，并不会释放锁，又不像 sleep 那样一段时间后自动恢复，所以容易引起死锁。相对应的 resume 方法用于唤醒一个 suspend 的线程。
 * Object.wait
 * wait 会把当前持有的锁释放掉同时阻塞住，让出 CPU。当其他线程调用 Object.notify/notifyAll 时，会被唤醒，可能得到 CPU，并且获得锁。
 * LockSupport.park
 * 这就是锁了嘛，相对应的用 unpark 解锁。
 * Thread.stop
 * 该方法已过时，直接停止线程，同时会释放所有锁，太过暴力，容易导致数据不一致。
 *
 * @link https://blog.csdn.net/u014044812/article/details/79474575
 * @date 2020/12/9
 */
package cn.jdemo.juc.thread.阻塞与唤醒;